home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / drawpix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-04  |  26.8 KB  |  1,011 lines

  1. /* $Id: drawpix.c,v 3.14 1998/08/01 04:52:47 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: drawpix.c,v $
  26.  * Revision 3.14  1998/08/01 04:52:47  brianp
  27.  * fixed conformance problems in GL_DEPTH_COMPONENT and GL_STENCIL_INDEX code
  28.  *
  29.  * Revision 3.13  1998/07/17 03:24:16  brianp
  30.  * added Pixel.ScaleOrBiasRGBA field
  31.  *
  32.  * Revision 3.12  1998/06/28 22:32:22  brianp
  33.  * fixed Mac compilation problem (Randy Frank and Miklos Fazekas)
  34.  *
  35.  * Revision 3.11  1998/06/01 00:38:13  brianp
  36.  * fixed off-by-one bug in glDrawPixels clipping (Randy Frank)
  37.  *
  38.  * Revision 3.10  1998/05/31 23:50:36  brianp
  39.  * cleaned up a few Solaris compiler warnings
  40.  *
  41.  * Revision 3.9  1998/04/01 02:58:52  brianp
  42.  * applied Miklos Fazekas's 3-31-98 Macintosh changes
  43.  *
  44.  * Revision 3.8  1998/03/27 03:39:14  brianp
  45.  * fixed G++ warnings
  46.  *
  47.  * Revision 3.7  1998/03/26 03:09:09  brianp
  48.  * added GL_LUMINANCE and GL_LUMINANCE_ALPHA to gl_direct_DrawPixels()
  49.  *
  50.  * Revision 3.6  1998/03/25 01:56:03  brianp
  51.  * fixed bug when Zoom.Y != 1.0 and top/bottom clipping needed (Randy Frank)
  52.  *
  53.  * Revision 3.5  1998/03/22 16:42:30  brianp
  54.  * added CI->RGBA conversion to gl_direct_DrawPixels()
  55.  *
  56.  * Revision 3.4  1998/03/10 01:28:22  brianp
  57.  * moved a few DEFARRY macros
  58.  *
  59.  * Revision 3.3  1998/02/08 20:22:14  brianp
  60.  * LOTS of clean-up and rewriting
  61.  *
  62.  * Revision 3.2  1998/02/04 00:33:45  brianp
  63.  * fixed a few cast problems for Amiga StormC compiler
  64.  *
  65.  * Revision 3.1  1998/02/01 22:16:34  brianp
  66.  * include different headers (zooming)
  67.  *
  68.  * Revision 3.0  1998/01/31 20:51:03  brianp
  69.  * initial rev
  70.  *
  71.  */
  72.  
  73.  
  74. #ifdef PC_HEADER
  75. #include "all.h"
  76. #else
  77. #include <assert.h>
  78. #include <stdlib.h>
  79. #include <string.h>
  80. #include "context.h"
  81. #include "drawpix.h"
  82. #include "feedback.h"
  83. #include "image.h"
  84. #include "macros.h"
  85. #include "pixel.h"
  86. #include "span.h"
  87. #include "stencil.h"
  88. #include "types.h"
  89. #include "zoom.h"
  90. #endif
  91.  
  92.  
  93.  
  94. /* TODO:  apply texture mapping to fragments */
  95.  
  96.  
  97. /*
  98.  * Try to do a fast glDrawPixels.  Conditions include:
  99.  *   not using a display list
  100.  *   simple pixel unpacking
  101.  *   no raster ops
  102.  *   etc....
  103.  * Return:  GL_TRUE if success, GL_FALSE if slow path must be used instead
  104.  */
  105. GLboolean gl_direct_DrawPixels( GLcontext *ctx,
  106.                 const struct gl_pixelstore_attrib *unpack,
  107.                 GLsizei width, GLsizei height,
  108.                 GLenum format, GLenum type,
  109.                 const GLvoid *pixels )
  110. {
  111.    GLubyte rgb[MAX_WIDTH][3];
  112.    GLubyte rgba[MAX_WIDTH][4];
  113.  
  114.    if (INSIDE_BEGIN_END(ctx)) {
  115.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels" );
  116.       return GL_TRUE;
  117.    }
  118.  
  119.    if (!ctx->Current.RasterPosValid) {
  120.       /* no-op */
  121.       return GL_TRUE;
  122.    }
  123.  
  124.    if (ctx->NewState) {
  125.       gl_update_state(ctx);
  126.    }
  127.  
  128.    /* see if device driver can do the drawpix */
  129.    if (ctx->Driver.DrawPixels) {
  130.       GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  131.       GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  132.       if ((*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type,
  133.                     unpack, pixels))
  134.      return GL_TRUE;
  135.    }
  136.  
  137.    if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0
  138.        && ctx->Pixel.RedBias==0.0 && ctx->Pixel.RedScale==1.0
  139.        && ctx->Pixel.GreenBias==0.0 && ctx->Pixel.GreenScale==1.0
  140.        && ctx->Pixel.BlueBias==0.0 && ctx->Pixel.BlueScale==1.0
  141.        && ctx->Pixel.AlphaBias==0.0 && ctx->Pixel.AlphaScale==1.0
  142.        && ctx->Pixel.IndexShift==0 && ctx->Pixel.IndexOffset==0
  143.        && ctx->Pixel.MapColorFlag==0
  144.        && unpack->Alignment==1
  145.        && !unpack->SwapBytes
  146.        && !unpack->LsbFirst) {
  147.  
  148.       GLint destX = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  149.       GLint destY = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  150.       GLint drawWidth = width;           /* actual width drawn */
  151.       GLint drawHeight = height;         /* actual height drawn */
  152.       GLint skipPixels = unpack->SkipPixels;
  153.       GLint skipRows = unpack->SkipRows;
  154.       GLint rowLength;
  155.       GLdepth zSpan[MAX_WIDTH];  /* only used when zooming */
  156.       GLint zoomY0;
  157.  
  158.       if (unpack->RowLength > 0)
  159.      rowLength = unpack->RowLength;
  160.       else
  161.      rowLength = width;
  162.  
  163.       /* If we're not using pixel zoom then do all clipping calculations
  164.        * now.  Otherwise, we'll let the gl_write_zoomed_*_span() functions
  165.        * handle the clipping.
  166.        */
  167.       if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  168.      /* horizontal clipping */
  169.      if (destX < ctx->Buffer->Xmin) {
  170.         skipPixels += (ctx->Buffer->Xmin - destX);
  171.         drawWidth  -= (ctx->Buffer->Xmin - destX);
  172.         destX = ctx->Buffer->Xmin;
  173.      }
  174.      if (destX + drawWidth > ctx->Buffer->Xmax)
  175.         drawWidth -= (destX + drawWidth - ctx->Buffer->Xmax - 1);
  176.      if (drawWidth <= 0)
  177.         return GL_TRUE;
  178.  
  179.      /* vertical clipping */
  180.      if (destY < ctx->Buffer->Ymin) {
  181.         skipRows   += (ctx->Buffer->Ymin - destY);
  182.         drawHeight -= (ctx->Buffer->Ymin - destY);
  183.         destY = ctx->Buffer->Ymin;
  184.      }
  185.      if (destY + drawHeight > ctx->Buffer->Ymax)
  186.         drawHeight -= (destY + drawHeight - ctx->Buffer->Ymax - 1);
  187.      if (drawHeight <= 0)
  188.         return GL_TRUE;
  189.       }
  190.       else {
  191.      /* setup array of fragment Z value to pass to zoom function */
  192.      GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  193.      GLint i;
  194.      assert(drawWidth < MAX_WIDTH);
  195.      for (i=0; i<drawWidth; i++)
  196.         zSpan[i] = z;
  197.  
  198.      /* save Y value of first row */
  199.      zoomY0 = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  200.       }
  201.  
  202.  
  203.       /*
  204.        * Ready to draw!
  205.        * The window region at (destX, destY) of size (drawWidth, drawHeight)
  206.        * will be written to.
  207.        * We'll take pixel data from buffer pointed to by "pixels" but we'll
  208.        * skip "skipRows" rows and skip "skipPixels" pixels/row.
  209.        */
  210.  
  211.       if (format==GL_RGBA && type==GL_UNSIGNED_BYTE) {
  212.      if (ctx->Visual->RGBAflag) {
  213.         GLubyte *src = (GLubyte *) pixels
  214.            + (skipRows * rowLength + skipPixels) * 4;
  215.         if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  216.            /* no zooming */
  217.            GLint row;
  218.            for (row=0; row<drawHeight; row++) {
  219.           (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
  220.                            (void *) src, NULL);
  221.           src += rowLength * 4;
  222.           destY++;
  223.            }
  224.         }
  225.         else {
  226.            /* with zooming */
  227.            GLint row;
  228.            for (row=0; row<drawHeight; row++) {
  229.           gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
  230.                         zSpan, (void *) src, zoomY0);
  231.           src += rowLength * 4;
  232.           destY++;
  233.            }
  234.         }
  235.      }
  236.      return GL_TRUE;
  237.       }
  238.       else if (format==GL_RGB && type==GL_UNSIGNED_BYTE) {
  239.      if (ctx->Visual->RGBAflag) {
  240.         GLubyte *src = (GLubyte *) pixels
  241.            + (skipRows * rowLength + skipPixels) * 3;
  242.         if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  243.            GLint row;
  244.            for (row=0; row<drawHeight; row++) {
  245.           (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
  246.                           (void *) src, NULL);
  247.           src += rowLength * 3;
  248.           destY++;
  249.            }
  250.         }
  251.         else {
  252.            /* with zooming */
  253.            GLint row;
  254.            for (row=0; row<drawHeight; row++) {
  255.           gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
  256.                        zSpan, (void *) src, zoomY0);
  257.           src += rowLength * 3;
  258.           destY++;
  259.            }
  260.         }
  261.      }
  262.      return GL_TRUE;
  263.       }
  264.       else if (format==GL_LUMINANCE && type==GL_UNSIGNED_BYTE) {
  265.      if (ctx->Visual->RGBAflag) {
  266.         GLubyte *src = (GLubyte *) pixels
  267.            + (skipRows * rowLength + skipPixels);
  268.         if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  269.            /* no zooming */
  270.            GLint row;
  271.            assert(drawWidth < MAX_WIDTH);
  272.            for (row=0; row<drawHeight; row++) {
  273.           GLint i;
  274.           for (i=0;i<drawWidth;i++) {
  275.              rgb[i][0] = src[i];
  276.              rgb[i][1] = src[i];
  277.              rgb[i][2] = src[i];
  278.           }
  279.           (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
  280.                           (void *) rgb, NULL);
  281.           src += rowLength;
  282.           destY++;
  283.            }
  284.         }
  285.         else {
  286.            /* with zooming */
  287.            GLint row;
  288.            assert(drawWidth < MAX_WIDTH);
  289.            for (row=0; row<drawHeight; row++) {
  290.           GLint i;
  291.           for (i=0;i<drawWidth;i++) {
  292.              rgb[i][0] = src[i];
  293.              rgb[i][1] = src[i];
  294.              rgb[i][2] = src[i];
  295.           }
  296.           gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY,
  297.                        zSpan, (void *) rgb, zoomY0);
  298.           src += rowLength;
  299.           destY++;
  300.            }
  301.         }
  302.      }
  303.      return GL_TRUE;
  304.       }
  305.       else if (format==GL_LUMINANCE_ALPHA && type==GL_UNSIGNED_BYTE) {
  306.      if (ctx->Visual->RGBAflag) {
  307.         GLubyte *src = (GLubyte *) pixels
  308.            + (skipRows * rowLength + skipPixels)*2;
  309.         if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  310.            /* no zooming */
  311.            GLint row;
  312.            assert(drawWidth < MAX_WIDTH);
  313.            for (row=0; row<drawHeight; row++) {
  314.           GLint i;
  315.           GLubyte *ptr = src;
  316.           for (i=0;i<drawWidth;i++) {
  317.              rgba[i][0] = *ptr;
  318.              rgba[i][1] = *ptr;
  319.              rgba[i][2] = *ptr++;
  320.              rgba[i][3] = *ptr++;
  321.           }
  322.           (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
  323.                            (void *) rgba, NULL);
  324.           src += rowLength*2;
  325.           destY++;
  326.            }
  327.         }
  328.         else {
  329.            /* with zooming */
  330.            GLint row;
  331.            assert(drawWidth < MAX_WIDTH);
  332.            for (row=0; row<drawHeight; row++) {
  333.           GLubyte *ptr = src;
  334.           GLint i;
  335.           for (i=0;i<drawWidth;i++) {
  336.              rgba[i][0] = *ptr;
  337.              rgba[i][1] = *ptr;
  338.              rgba[i][2] = *ptr++;
  339.              rgba[i][3] = *ptr++;
  340.           }
  341.           gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
  342.                         zSpan, (void *) rgba, zoomY0);
  343.           src += rowLength*2;
  344.           destY++;
  345.            }
  346.         }
  347.      }
  348.      return GL_TRUE;
  349.       }
  350.       else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) {
  351.      GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels;
  352.      if (ctx->Visual->RGBAflag) {
  353.         /* convert CI data to RGBA */
  354.         if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  355.            /* no zooming */
  356.            GLint row;
  357.            for (row=0; row<drawHeight; row++) {
  358.           assert(drawWidth < MAX_WIDTH);
  359.           gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
  360. #ifndef __STORM__
  361.           (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
  362.                            rgba, NULL);
  363. #else
  364.           (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
  365.                            (CONST GLubyte(*)[4])rgba, NULL);
  366. #endif
  367.           src += rowLength;
  368.           destY++;
  369.            }
  370.            return GL_TRUE;
  371.         }
  372.         else {
  373.            /* with zooming */
  374.            GLint row;
  375.            for (row=0; row<drawHeight; row++) {
  376.           assert(drawWidth < MAX_WIDTH);
  377.           gl_map_ci8_to_rgba(ctx, drawWidth, src, rgba);
  378.           gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY,
  379.                         zSpan, (void *) rgba, zoomY0);
  380.           src += rowLength;
  381.           destY++;
  382.            }
  383.            return GL_TRUE;
  384.         }
  385.      }
  386.      else {
  387.         /* write CI data to CI frame buffer */
  388.         GLint row;
  389.         if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
  390.            /* no zooming */
  391.            for (row=0; row<drawHeight; row++) {
  392.           (*ctx->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY,
  393.                           src, NULL);
  394.           src += rowLength;
  395.           destY++;
  396.            }
  397.            return GL_TRUE;
  398.         }
  399.         else {
  400.            /* with zooming */
  401.            return GL_FALSE;
  402.         }
  403.      }
  404.       }
  405.       else {
  406.      /* can't handle this pixel format and/or data type here */
  407.      return GL_FALSE;
  408.       }
  409.    }
  410.    else {
  411.       /* can't do direct render, have to use slow path */
  412.       return GL_FALSE;
  413.    }
  414. }
  415.  
  416.  
  417.  
  418. /*
  419.  * Do glDrawPixels of index pixels.
  420.  */
  421. static void draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
  422.                    const struct gl_image *image )
  423. {
  424.    GLint width, height, widthInBytes;
  425.    const GLint desty = y;
  426.    GLint i, j;
  427.    GLdepth zspan[MAX_WIDTH];
  428.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  429.  
  430.    assert(image);
  431.    assert(image->Format == GL_COLOR_INDEX);
  432.  
  433.    width = image->Width;
  434.    height = image->Height;
  435.    if (image->Type == GL_BITMAP)
  436.       widthInBytes = (width + 7) / 8;
  437.    else
  438.       widthInBytes = width;
  439.  
  440.    /* Fragment depth values */
  441.    if (ctx->Depth.Test) {
  442.       GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  443.       for (i=0;i<width;i++) {
  444.      zspan[i] = zval;
  445.       }
  446.    }
  447.  
  448.    /* process the image row by row */
  449.    for (i=0;i<height;i++,y++) {
  450.       GLuint ispan[MAX_WIDTH];
  451.  
  452.       /* convert to uints */
  453.       switch (image->Type) {
  454.      case GL_UNSIGNED_BYTE:
  455.         {
  456.            GLubyte *src = (GLubyte *) image->Data + i * width;
  457.            for (j=0;j<width;j++) {
  458.           ispan[j] = (GLuint) *src++;
  459.            }
  460.         }
  461.         break;
  462.      case GL_FLOAT:
  463.         {
  464.            GLfloat *src = (GLfloat *) image->Data + i * width;
  465.            for (j=0;j<width;j++) {
  466.           ispan[j] = (GLuint) (GLint) *src++;
  467.            }
  468.         }
  469.         break;
  470.      case GL_BITMAP:
  471.         {
  472.            GLubyte *src = (GLubyte *) image->Data + i * widthInBytes;
  473.            for (j=0;j<width;j++) {
  474.           ispan[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
  475.            }
  476.         }
  477.         break;
  478.      default:
  479.         gl_problem( ctx, "draw_index_pixels type" );
  480.         return;
  481.       }
  482.  
  483.       /* apply shift and offset */
  484.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  485.      gl_shift_and_offset_ci( ctx, width, ispan );
  486.       }
  487.  
  488.       if (ctx->Visual->RGBAflag) {
  489.      /* Convert index to RGBA and write to frame buffer */
  490.      GLubyte rgba[MAX_WIDTH][4];
  491.      gl_map_ci_to_rgba( ctx, width, ispan, rgba );
  492.      if (zoom) {
  493. #ifndef __STORM__
  494.         gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, rgba, desty );
  495. #else
  496.         gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, (CONST GLubyte(*)[4])rgba, desty );
  497. #endif
  498.      }
  499.      else {
  500.         gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
  501.      }
  502.       }
  503.       else {
  504.      /* optionally apply index map then write to frame buffer */
  505.      if (ctx->Pixel.MapColorFlag) {
  506.         gl_map_ci(ctx, width, ispan);
  507.      }
  508.      if (zoom) {
  509.         gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty );
  510.      }
  511.      else {
  512.         gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  513.      }
  514.       }
  515.    }
  516.  
  517. }
  518.  
  519.  
  520.  
  521. /*
  522.  * Do glDrawPixels of stencil image.  The image datatype may either
  523.  * be GLubyte or GLbitmap.
  524.  */
  525. static void draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
  526.                  const struct gl_image *image )
  527. {
  528.    GLint widthInBytes, width, height;
  529.    const GLint desty = y;
  530.    GLint i;
  531.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  532.  
  533.    assert(image);
  534.    assert(image->Format == GL_STENCIL_INDEX);
  535.    assert(image->Type == GL_UNSIGNED_BYTE || image->Type == GL_BITMAP);
  536.  
  537.    if (image->Type == GL_UNSIGNED_BYTE)
  538.       widthInBytes = image->Width;
  539.    else
  540.       widthInBytes = (image->Width + 7) / 8;
  541.    width = image->Width;
  542.    height = image->Height;
  543.  
  544.    /* process the image row by row */
  545.    for (i=0;i<height;i++,y++) {
  546.       GLstencil *src = (GLstencil*)image->Data + i * widthInBytes;
  547.       GLstencil *stencilValues;
  548.       GLstencil stencilCopy[MAX_WIDTH];
  549.  
  550.       if (image->Type == GL_BITMAP) {
  551.      /* convert bitmap data to GLubyte (0 or 1) data */
  552.      GLint j;
  553.      for (j = 0; j < width; j++) {
  554.         stencilCopy[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1;
  555.      }
  556.      src = stencilCopy;
  557.       }
  558.  
  559.       if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift
  560.       || ctx->Pixel.MapStencilFlag) {
  561.  
  562.      /* make copy of stencil values */
  563.      if (src != stencilCopy)
  564.         MEMCPY( stencilCopy, src, width * sizeof(GLstencil));
  565.  
  566.      /* apply shift and offset */
  567.      if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) {
  568.         gl_shift_and_offset_stencil( ctx, width, stencilCopy );
  569.      }
  570.  
  571.      /* mapping */
  572.      if (ctx->Pixel.MapStencilFlag) {
  573.         gl_map_stencil( ctx, width, stencilCopy );
  574.      }
  575.  
  576.      stencilValues = stencilCopy;
  577.       }
  578.       else {
  579.      /* use stencil values in-place */
  580.      stencilValues = src;
  581.       }
  582.  
  583.       /* write stencil values to stencil buffer */
  584.       if (zoom) {
  585.      gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y,
  586.                        stencilValues, desty );
  587.       }
  588.       else {
  589.      gl_write_stencil_span( ctx, (GLuint) width, x, y, stencilValues );
  590.       }
  591.    }
  592. }
  593.  
  594.  
  595.  
  596. /*
  597.  * Do a glDrawPixels of depth values.
  598.  */
  599. static void draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
  600.                    const struct gl_image *image )
  601. {
  602.    GLint width, height;
  603.    const GLint desty = y;
  604.    GLubyte rgba[MAX_WIDTH][4];
  605.    GLuint ispan[MAX_WIDTH];
  606.    const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
  607.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  608.  
  609.    assert(image);
  610.    assert(image->Format == GL_DEPTH_COMPONENT);
  611.  
  612.    width = image->Width;
  613.    height = image->Height;
  614.  
  615.    /* Color or index */
  616.    if (ctx->Visual->RGBAflag) {
  617.       GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F);
  618.       GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0F);
  619.       GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0F);
  620.       GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F);
  621.       GLint i;
  622.       for (i=0; i<width; i++) {
  623.      rgba[i][RCOMP] = r;
  624.      rgba[i][GCOMP] = g;
  625.      rgba[i][BCOMP] = b;
  626.      rgba[i][ACOMP] = a;
  627.       }
  628.    }
  629.    else {
  630.       GLint i;
  631.       for (i=0;i<width;i++) {
  632.      ispan[i] = ctx->Current.RasterIndex;
  633.       }
  634.    }
  635.  
  636.    if (image->Type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  637.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  638.       /* Special case: directly write 16-bit depth values */
  639.       GLint j;
  640.       for (j=0;j<height;j++,y++) {
  641.      GLdepth *zptr = (GLdepth *) image->Data + j * width;
  642.      gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP );
  643.       }
  644.    }
  645.    else if (image->Type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  646.        && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) {
  647.       /* Special case: directly write 32-bit depth values */
  648.       GLint i, j;
  649.       /* Compute shift value to scale 32-bit uints down to depth values. */
  650.       GLuint shift = 0;
  651.       GLuint max = MAX_DEPTH;
  652.       while ((max&0x80000000)==0) {
  653.      max = max << 1;
  654.      shift++;
  655.       }
  656.       for (j=0;j<height;j++,y++) {
  657.      GLdepth zspan[MAX_WIDTH];
  658.      GLuint *zptr = (GLuint *) image->Data + j * width;
  659.      for (i=0;i<width;i++) {
  660.         zspan[i] = zptr[i] >> shift;
  661.      }
  662.      gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
  663.       }
  664.    }
  665.    else {
  666.       /* General case (slower) */
  667.       GLint i, j;
  668.  
  669.       /* process image row by row */
  670.       for (i=0;i<height;i++,y++) {
  671.      GLfloat depth[MAX_WIDTH];
  672.      GLdepth zspan[MAX_WIDTH];
  673.  
  674.      switch (image->Type) {
  675.         case GL_UNSIGNED_SHORT:
  676.            {
  677.           GLushort *src = (GLushort *) image->Data + i * width;
  678.           for (j=0;j<width;j++) {
  679.              depth[j] = USHORT_TO_FLOAT( *src++ );
  680.           }
  681.            }
  682.            break;
  683.         case GL_UNSIGNED_INT:
  684.            {
  685.           GLuint *src = (GLuint *) image->Data + i * width;
  686.           for (j=0;j<width;j++) {
  687.              depth[j] = UINT_TO_FLOAT( *src++ );
  688.           }
  689.            }
  690.            break;
  691.         case GL_FLOAT:
  692.            {
  693.           GLfloat *src = (GLfloat *) image->Data + i * width;
  694.           for (j=0;j<width;j++) {
  695.              depth[j] = *src++;
  696.           }
  697.            }
  698.            break;
  699.         default:
  700.            gl_problem(ctx, "Bad type in draw_depth_pixels");
  701.            return;
  702.      }
  703.  
  704.      /* apply depth scale and bias */
  705.      if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) {
  706.         for (j=0;j<width;j++) {
  707.            depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  708.         }
  709.      }
  710.  
  711.      /* clamp depth values to [0,1] and convert from floats to integers */
  712.      for (j=0;j<width;j++) {
  713.         zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE);
  714.      }
  715.  
  716.      if (ctx->Visual->RGBAflag) {
  717.         if (zoom) {
  718. #ifndef __STORM__
  719.            gl_write_zoomed_rgba_span( ctx, width, x, y, zspan,
  720.                       rgba, desty );
  721. #else
  722.            gl_write_zoomed_rgba_span( ctx, width, x, y, zspan,
  723.                       (CONST GLubyte(*)[4])rgba, desty );
  724. #endif
  725.         }
  726.         else {
  727.            gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP );
  728.         }
  729.      }
  730.      else {
  731.         if (zoom) {
  732.            gl_write_zoomed_index_span( ctx, width, x, y, zspan,
  733.                        ispan, GL_BITMAP );
  734.         }
  735.         else {
  736.            gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP );
  737.         }
  738.      }
  739.  
  740.       }
  741.    }
  742. }
  743.  
  744.  
  745.  
  746. /* Simple unpacking parameters: */
  747. static struct gl_pixelstore_attrib NoUnpack = {
  748.    1,            /* Alignment */
  749.    0,            /* RowLength */
  750.    0,            /* SkipPixels */
  751.    0,            /* SkipRows */
  752.    0,            /* ImageHeight */
  753.    0,            /* SkipImages */
  754.    GL_FALSE,     /* SwapBytes */
  755.    GL_FALSE      /* LsbFirst */
  756. };
  757.  
  758.  
  759. /*
  760.  * Do glDrawPixels of RGBA pixels.
  761.  */
  762. static void draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
  763.                   const struct gl_image *image )
  764. {
  765.    GLint width, height;
  766.    GLint i, j;
  767.    const GLint desty = y;
  768.    GLdepth zspan[MAX_WIDTH];
  769.    GLboolean quickDraw;
  770.    const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
  771.  
  772.    assert(image);
  773.  
  774.    /* Try an optimized glDrawPixels first */
  775.    if (gl_direct_DrawPixels(ctx, &NoUnpack, image->Width, image->Height,
  776.                 image->Format, image->Type, image->Data ))
  777.       return;
  778.  
  779.    width = image->Width;
  780.    height = image->Height;
  781.  
  782.    /* Fragment depth values */
  783.    if (ctx->Depth.Test) {
  784.       /* fill in array of z values */
  785.       GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE);
  786.       for (i=0;i<width;i++) {
  787.      zspan[i] = z;
  788.       }
  789.    }
  790.  
  791.    if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0
  792.        && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) {
  793.       quickDraw = GL_TRUE;
  794.    }
  795.    else {
  796.       quickDraw = GL_FALSE;
  797.    }
  798.  
  799.    {
  800.       /* General solution */
  801.       GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  802.       GLuint components;
  803.       DEFARRAY(GLfloat, rf, MAX_WIDTH);
  804.       DEFARRAY(GLfloat, gf, MAX_WIDTH);
  805.       DEFARRAY(GLfloat, bf, MAX_WIDTH);
  806.       DEFARRAY(GLfloat, af, MAX_WIDTH);
  807.       GLubyte rgba[MAX_WIDTH][4];
  808.  
  809.       r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  810.       switch (image->Format) {
  811.      case GL_RED:
  812.         r_flag = GL_TRUE;
  813.         components = 1;
  814.         break;
  815.      case GL_GREEN:
  816.         g_flag = GL_TRUE;
  817.         components = 1;
  818.         break;
  819.      case GL_BLUE:
  820.         b_flag = GL_TRUE;
  821.         components = 1;
  822.         break;
  823.      case GL_ALPHA:
  824.         a_flag = GL_TRUE;
  825.         components = 1;
  826.         break;
  827.      case GL_RGB:
  828.         r_flag = g_flag = b_flag = GL_TRUE;
  829.         components = 3;
  830.         break;
  831.      case GL_LUMINANCE:
  832.         l_flag = GL_TRUE;
  833.         components = 1;
  834.         break;
  835.      case GL_LUMINANCE_ALPHA:
  836.         l_flag = a_flag = GL_TRUE;
  837.         components = 2;
  838.         break;
  839.      case GL_RGBA:
  840.         r_flag = g_flag = b_flag = a_flag = GL_TRUE;
  841.         components = 4;
  842.         break;
  843.      default:
  844.         gl_problem(ctx, "Bad type in draw_rgba_pixels");
  845.         goto cleanup;
  846.       }
  847.  
  848.       /* process the image row by row */
  849.       for (i=0;i<height;i++,y++) {
  850.      /* convert to floats */
  851.      switch (image->Type) {
  852.         case GL_UNSIGNED_BYTE:
  853.            {
  854.           GLubyte *src = (GLubyte *) image->Data + i * width * components;
  855.           for (j=0;j<width;j++) {
  856.              if (l_flag) {
  857.             rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++);
  858.              }
  859.              else {
  860.             rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  861.             gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  862.             bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0;
  863.              }
  864.              af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0;
  865.           }
  866.            }
  867.            break;
  868.         case GL_FLOAT:
  869.            {
  870.           GLfloat *src = (GLfloat *) image->Data + i * width * components;
  871.           for (j=0;j<width;j++) {
  872.              if (l_flag) {
  873.             rf[j] = gf[j] = bf[j] = *src++;
  874.              }
  875.              else {
  876.             rf[j] = r_flag ? *src++ : 0.0;
  877.             gf[j] = g_flag ? *src++ : 0.0;
  878.             bf[j] = b_flag ? *src++ : 0.0;
  879.              }
  880.              af[j] = a_flag ? *src++ : 1.0;
  881.           }
  882.            }
  883.            break;
  884.         default:
  885.            gl_problem( ctx, "draw_rgba_pixels type" );
  886.            goto cleanup;
  887.      }
  888.  
  889.      /* apply scale and bias */
  890.      if (ctx->Pixel.ScaleOrBiasRGBA) {
  891.         gl_scale_and_bias_color(ctx, width, rf, gf, bf, af);
  892.      }
  893.  
  894.      /* apply pixel mappings */
  895.      if (ctx->Pixel.MapColorFlag) {
  896.         gl_map_color(ctx, width, rf, gf, bf, af);
  897.      }
  898.  
  899.      /* convert to integers */
  900.      for (j=0;j<width;j++) {
  901.         rgba[j][RCOMP] = (GLint) (rf[j] * 255.0F);
  902.         rgba[j][GCOMP] = (GLint) (gf[j] * 255.0F);
  903.         rgba[j][BCOMP] = (GLint) (bf[j] * 255.0F);
  904.         rgba[j][ACOMP] = (GLint) (af[j] * 255.0F);
  905.      }
  906.  
  907.      /* write to frame buffer */
  908.      if (quickDraw) {
  909. #ifndef __STORM__
  910.         (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, rgba, NULL);
  911. #else
  912.         (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, (CONST GLubyte(*)[4])rgba, NULL);
  913. #endif
  914.      }
  915.      else if (zoom) {
  916. #ifndef __STORM__
  917.         gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, rgba, desty );
  918. #else
  919.         gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, (CONST GLubyte(*)[4])rgba, desty );
  920. #endif
  921.      }
  922.      else {
  923.         gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, rgba, GL_BITMAP);
  924.      }
  925.       }
  926. cleanup:
  927.       UNDEFARRAY(rf);
  928.       UNDEFARRAY(gf);
  929.       UNDEFARRAY(bf);
  930.       UNDEFARRAY(af);
  931.    }
  932. }
  933.  
  934.  
  935.  
  936. /*
  937.  * Execute glDrawPixels
  938.  */
  939. void gl_DrawPixels( GLcontext* ctx, struct gl_image *image )
  940. {
  941.    if (INSIDE_BEGIN_END(ctx)) {
  942.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels" );
  943.       return;
  944.    }
  945.  
  946.    if (gl_image_error_test( ctx, image, "glDrawPixels" ))
  947.       return;
  948.  
  949.    if (ctx->RenderMode==GL_RENDER) {
  950.       GLint x, y;
  951.       if (!ctx->Current.RasterPosValid) {
  952.      return;
  953.       }
  954.  
  955.       x = (GLint) (ctx->Current.RasterPos[0] + 0.5F);
  956.       y = (GLint) (ctx->Current.RasterPos[1] + 0.5F);
  957.  
  958.       switch (image->Format) {
  959.      case GL_COLOR_INDEX:
  960.         draw_index_pixels( ctx, x, y, image );
  961.         break;
  962.      case GL_STENCIL_INDEX:
  963.         draw_stencil_pixels( ctx, x, y, image );
  964.         break;
  965.      case GL_DEPTH_COMPONENT:
  966.         draw_depth_pixels( ctx, x, y, image );
  967.         break;
  968.      case GL_RED:
  969.      case GL_GREEN:
  970.      case GL_BLUE:
  971.      case GL_ALPHA:
  972.      case GL_RGB:
  973.      case GL_LUMINANCE:
  974.      case GL_LUMINANCE_ALPHA:
  975.      case GL_RGBA:
  976.         draw_rgba_pixels( ctx, x, y, image );
  977.         break;
  978.      default:
  979.         gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" );
  980.         return;
  981.       }
  982.    }
  983.    else if (ctx->RenderMode==GL_FEEDBACK) {
  984.       if (ctx->Current.RasterPosValid) {
  985.      GLfloat color[4], texcoord[4], invq;
  986.      color[0] = (GLfloat) ctx->Current.ByteColor[0] / 255.0;
  987.      color[1] = (GLfloat) ctx->Current.ByteColor[1] / 255.0;
  988.      color[2] = (GLfloat) ctx->Current.ByteColor[2] / 255.0;
  989.      color[3] = (GLfloat) ctx->Current.ByteColor[3] / 255.0;
  990.      invq = 1.0F / ctx->Current.TexCoord[3];
  991.      texcoord[0] = ctx->Current.TexCoord[0] * invq;
  992.      texcoord[1] = ctx->Current.TexCoord[1] * invq;
  993.      texcoord[2] = ctx->Current.TexCoord[2] * invq;
  994.      texcoord[3] = ctx->Current.TexCoord[3];
  995.      FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
  996.      gl_feedback_vertex( ctx,
  997.                  ctx->Current.RasterPos[0],
  998.                  ctx->Current.RasterPos[1],
  999.                  ctx->Current.RasterPos[2],
  1000.                  ctx->Current.RasterPos[3],
  1001.                  color, ctx->Current.Index, texcoord );
  1002.       }
  1003.    }
  1004.    else if (ctx->RenderMode==GL_SELECT) {
  1005.       if (ctx->Current.RasterPosValid) {
  1006.      gl_update_hitflag( ctx, ctx->Current.RasterPos[2] );
  1007.       }
  1008.    }
  1009. }
  1010.  
  1011.